#    GMail-Notifier - A cooler looking gmail notifier for Ubuntu
#    Copyright (C) 2009 Uday K Verma
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import sys
import urllib2
import urllib

from xml.dom.minidom import parseString

class Author(object):
    def __init__(self, name, email):
        self.name = name
        self.email = email
        
    def __repr__(self):
        if self.name == self.email:
            return self.name
        return "%s (%s)" % (self.name, self.email)
        
class Mail(object):
    def __init__(self, title, summary, label, link, modified, issued, id, authors):
        self.title = title
        self.summary = summary
        self.label = label
        self.link = link
        self.modified = modified
        self.issued = issued
        self.id = id
        self.authors = authors
        
    def __str__(self):
        return '%s - %s : %s' % (self.title, self.summary, ','.join ([str(a) for a in self.authors]))

class GMailAtomReader(object):
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.feeds = []
        
    def set_feeds(self, fs):
        self.feeds = fs
        
    def _get_text (self, nl):
        t = ""
        for n in nl:
            if n.nodeType == n.TEXT_NODE:
                t = t + n.data
        return t
        
    def _get_feed(self, label = None):
        try:
            if label:
                gmail = 'mail.google.com/gmail/feed/atom/%s/' % (label)
            else:
                gmail = 'mail.google.com/gmail/feed/atom'
                
            # encode URL
            gmail = urllib.quote (gmail)
            
            '''The method to do HTTPBasicAuthentication'''
            auth_handler = urllib2.HTTPBasicAuthHandler()
            auth_handler.add_password(realm='New mail feed',
                uri='https://mail.google.com/',
                user= self.username,
                passwd= self.password)
            
            opener = urllib2.build_opener(auth_handler)
            urllib2.install_opener(opener)
            
            response = urllib2.urlopen("https://" + gmail)
            feed = response.read()
            return feed
        except Exception, e:
            print "Error while parsing feed: ", str(e)
            raise e
    
    def _get_mail_count (self, atom):
        return int(self._get_text(atom.getElementsByTagName ('fullcount')[0].childNodes))
    
    def _get_data (self, e, tag):
        return self._get_text (e.getElementsByTagName (tag)[0].childNodes)
    
    def _get_link(self, e):
        return e.getElementsByTagName ('link')[0].getAttribute ('href')
    
    def _get_authors(self, e):
        auths = e.getElementsByTagName ('author')
        authors = []
        for a in auths:
            name = self._get_data (a, 'name')
            email = self._get_data (a, 'email')
        
            authors.append ((name, email))
        
        return authors
    
    def _parse_mails (self, atom, label = None):
        ents = atom.getElementsByTagName ('entry')
        emails = []
    
        for e in ents:
            title = self._get_data (e, 'title')
            summary = self._get_data (e, 'summary')
            link = self._get_link (e)
            modified = self._get_data (e, 'modified')
            issued = self._get_data (e, 'issued')
            id = self._get_data (e, 'id')
            authors = self._get_authors (e)
            emails.append (
                Mail (title, summary, label, link, modified, issued, id,
                      [Author(n,e) for n,e in authors])
            )
        
        return emails
        
    def fetchMails (self):
        mails = []
        
        # fetch feeds
        for f in self.feeds:
            try:
                m = self._parse_mails (parseString (self._get_feed (f)), f)
                self._append_mails (mails, m)
            except Exception, e:
                print str(e)
                raise e
            
        # fetch inbox last, this will make sure that labeled mails have preference
        m = self._parse_mails (parseString (self._get_feed ()))
        self._append_mails (mails, m)
            
        return mails
    
    def _append_mails (self, mails, m):
        for _m in m:
            mails.append (_m)
        

    
            
            

